/**
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */

package com.amazonaws.util.awsclientgenerator.generators.cpp.ec2;

import com.amazonaws.util.awsclientgenerator.domainmodels.SdkFileEntry;
import com.amazonaws.util.awsclientgenerator.domainmodels.codegeneration.*;
import com.amazonaws.util.awsclientgenerator.domainmodels.codegeneration.Error;
import com.amazonaws.util.awsclientgenerator.generators.cpp.QueryCppClientGenerator;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;

import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class Ec2CppClientGenerator extends QueryCppClientGenerator{

    public Ec2CppClientGenerator() throws Exception {
        super();
    }

    @Override
    public SdkFileEntry[] generateSourceFiles(ServiceModel serviceModel) throws Exception {

        List<String> keysToRename = new LinkedList<>();
        Map<String, Shape> shapes = serviceModel.getShapes();
        for (final String key : shapes.keySet()) {
            final Shape shape = shapes.get(key);
            shape.setName(shape.getName().replaceAll("Result$", "Response"));
            shape.setType(shape.getType().replaceAll("Result$", "Response"));
            keysToRename.add(key);
        }

        for (final String key : keysToRename) {
            final Shape shape = shapes.get(key);
            shapes.remove(key);
            shapes.put(key.replaceAll("Result$", "Response"), shape);
        }

        //add "disabled" state to SpotInstanceState
        List<String> spotInstanceStateEnumValues = shapes.get("SpotInstanceState").getEnumValues();

        if(!spotInstanceStateEnumValues.contains("disabled")) {
            spotInstanceStateEnumValues.add("disabled");
        }

        final Collection<Error> serviceErrors = serviceModel.getServiceErrors();
        final Error activeVpcPeeringConnectionPerVpcLimitExceeded = new Error();
        activeVpcPeeringConnectionPerVpcLimitExceeded.setName("ActiveVpcPeeringConnectionPerVpcLimitExceeded");
        activeVpcPeeringConnectionPerVpcLimitExceeded.setText("ActiveVpcPeeringConnectionPerVpcLimitExceeded");
        serviceErrors.add(activeVpcPeeringConnectionPerVpcLimitExceeded);
        final Error addressLimitExceeded = new Error();
        addressLimitExceeded.setName("AddressLimitExceeded");
        addressLimitExceeded.setText("AddressLimitExceeded");
        serviceErrors.add(addressLimitExceeded);
        final Error attachmentLimitExceeded = new Error();
        attachmentLimitExceeded.setName("AttachmentLimitExceeded");
        attachmentLimitExceeded.setText("AttachmentLimitExceeded");
        serviceErrors.add(attachmentLimitExceeded);
        final Error bundlingInProgress = new Error();
        bundlingInProgress.setName("BundlingInProgress");
        bundlingInProgress.setText("BundlingInProgress");
        serviceErrors.add(bundlingInProgress);
        final Error cannotDelete = new Error();
        cannotDelete.setName("CannotDelete");
        cannotDelete.setText("CannotDelete");
        serviceErrors.add(cannotDelete);
        final Error concurrentSnapshotLimitExceeded = new Error();
        concurrentSnapshotLimitExceeded.setName("ConcurrentSnapshotLimitExceeded");
        concurrentSnapshotLimitExceeded.setText("ConcurrentSnapshotLimitExceeded");
        serviceErrors.add(concurrentSnapshotLimitExceeded);
        final Error concurrentTagAccess = new Error();
        concurrentTagAccess.setName("ConcurrentTagAccess");
        concurrentTagAccess.setText("ConcurrentTagAccess");
        serviceErrors.add(concurrentTagAccess);
        final Error customerGatewayLimitExceeded = new Error();
        customerGatewayLimitExceeded.setName("CustomerGatewayLimitExceeded");
        customerGatewayLimitExceeded.setText("CustomerGatewayLimitExceeded");
        serviceErrors.add(customerGatewayLimitExceeded);
        final Error dependencyViolation = new Error();
        dependencyViolation.setName("DependencyViolation");
        dependencyViolation.setText("DependencyViolation");
        serviceErrors.add(dependencyViolation);
        final Error diskImageSizeTooLarge = new Error();
        diskImageSizeTooLarge.setName("DiskImageSizeTooLarge");
        diskImageSizeTooLarge.setText("DiskImageSizeTooLarge");
        serviceErrors.add(diskImageSizeTooLarge);
        final Error dryRunOperation = new Error();
        dryRunOperation.setName("DryRunOperation");
        dryRunOperation.setText("DryRunOperation");
        serviceErrors.add(dryRunOperation);
        final Error encryptedVolumesNotSupported = new Error();
        encryptedVolumesNotSupported.setName("EncryptedVolumesNotSupported");
        encryptedVolumesNotSupported.setText("EncryptedVolumesNotSupported");
        serviceErrors.add(encryptedVolumesNotSupported);
        final Error flowLogAlreadyExists = new Error();
        flowLogAlreadyExists.setName("FlowLogAlreadyExists");
        flowLogAlreadyExists.setText("FlowLogAlreadyExists");
        serviceErrors.add(flowLogAlreadyExists);
        final Error flowLogsLimitExceeded = new Error();
        flowLogsLimitExceeded.setName("FlowLogsLimitExceeded");
        flowLogsLimitExceeded.setText("FlowLogsLimitExceeded");
        serviceErrors.add(flowLogsLimitExceeded);
        final Error filterLimitExceeded = new Error();
        filterLimitExceeded.setName("FilterLimitExceeded");
        filterLimitExceeded.setText("FilterLimitExceeded");
        serviceErrors.add(filterLimitExceeded);
        final Error gatewayNotAttached = new Error();
        gatewayNotAttached.setName("Gateway.NotAttached");
        gatewayNotAttached.setText("Gateway.NotAttached");
        serviceErrors.add(gatewayNotAttached);
        final Error incorrectInstanceState = new Error();
        incorrectInstanceState.setName("IncorrectInstanceState");
        incorrectInstanceState.setText("IncorrectInstanceState");
        serviceErrors.add(incorrectInstanceState);
        final Error incorrectState = new Error();
        incorrectState.setName("IncorrectState");
        incorrectState.setText("IncorrectState");
        serviceErrors.add(incorrectState);
        final Error instanceAlreadyLinked = new Error();
        instanceAlreadyLinked.setName("InstanceAlreadyLinked");
        instanceAlreadyLinked.setText("InstanceAlreadyLinked");
        serviceErrors.add(instanceAlreadyLinked);
        final Error instanceLimitExceeded = new Error();
        instanceLimitExceeded.setName("InstanceLimitExceeded");
        instanceLimitExceeded.setText("InstanceLimitExceeded");
        serviceErrors.add(instanceLimitExceeded);
        final Error insufficientFreeAddressesInSubnet = new Error();
        insufficientFreeAddressesInSubnet.setName("InsufficientFreeAddressesInSubnet");
        insufficientFreeAddressesInSubnet.setText("InsufficientFreeAddressesInSubnet");
        serviceErrors.add(insufficientFreeAddressesInSubnet);
        final Error insufficientReservedInstancesCapacity = new Error();
        insufficientReservedInstancesCapacity.setName("InsufficientReservedInstancesCapacity");
        insufficientReservedInstancesCapacity.setText("InsufficientReservedInstancesCapacity");
        serviceErrors.add(insufficientReservedInstancesCapacity);
        final Error internetGatewayLimitExceeded = new Error();
        internetGatewayLimitExceeded.setName("InternetGatewayLimitExceeded");
        internetGatewayLimitExceeded.setText("InternetGatewayLimitExceeded");
        serviceErrors.add(internetGatewayLimitExceeded);
        final Error invalidAddressMalformed = new Error();
        invalidAddressMalformed.setName("InvalidAddress.Malformed");
        invalidAddressMalformed.setText("InvalidAddress.Malformed");
        serviceErrors.add(invalidAddressMalformed);
        final Error invalidAddressNotFound = new Error();
        invalidAddressNotFound.setName("InvalidAddress.NotFound");
        invalidAddressNotFound.setText("InvalidAddress.NotFound");
        serviceErrors.add(invalidAddressNotFound);
        final Error invalidAddressIDNotFound = new Error();
        invalidAddressIDNotFound.setName("InvalidAddressID.NotFound");
        invalidAddressIDNotFound.setText("InvalidAddressID.NotFound");
        serviceErrors.add(invalidAddressIDNotFound);
        final Error invalidAllocationIDNotFound = new Error();
        invalidAllocationIDNotFound.setName("InvalidAllocationID.NotFound");
        invalidAllocationIDNotFound.setText("InvalidAllocationID.NotFound");
        serviceErrors.add(invalidAllocationIDNotFound);
        final Error invalidAMIAttributeItemValue = new Error();
        invalidAMIAttributeItemValue.setName("InvalidAMIAttributeItemValue");
        invalidAMIAttributeItemValue.setText("InvalidAMIAttributeItemValue");
        serviceErrors.add(invalidAMIAttributeItemValue);
        final Error invalidAMIIDMalformed = new Error();
        invalidAMIIDMalformed.setName("InvalidAMIID.Malformed");
        invalidAMIIDMalformed.setText("InvalidAMIID.Malformed");
        serviceErrors.add(invalidAMIIDMalformed);
        final Error invalidAMIIDNotFound = new Error();
        invalidAMIIDNotFound.setName("InvalidAMIID.NotFound");
        invalidAMIIDNotFound.setText("InvalidAMIID.NotFound");
        serviceErrors.add(invalidAMIIDNotFound);
        final Error invalidAMIIDUnavailable = new Error();
        invalidAMIIDUnavailable.setName("InvalidAMIID.Unavailable");
        invalidAMIIDUnavailable.setText("InvalidAMIID.Unavailable");
        serviceErrors.add(invalidAMIIDUnavailable);
        final Error invalidAMINameDuplicate = new Error();
        invalidAMINameDuplicate.setName("InvalidAMIName.Duplicate");
        invalidAMINameDuplicate.setText("InvalidAMIName.Duplicate");
        serviceErrors.add(invalidAMINameDuplicate);
        final Error invalidAMINameMalformed = new Error();
        invalidAMINameMalformed.setName("InvalidAMIName.Malformed");
        invalidAMINameMalformed.setText("InvalidAMIName.Malformed");
        serviceErrors.add(invalidAMINameMalformed);
        final Error invalidAssociationIDNotFound = new Error();
        invalidAssociationIDNotFound.setName("InvalidAssociationID.NotFound");
        invalidAssociationIDNotFound.setText("InvalidAssociationID.NotFound");
        serviceErrors.add(invalidAssociationIDNotFound);
        final Error invalidAttachmentNotFound = new Error();
        invalidAttachmentNotFound.setName("InvalidAttachment.NotFound");
        invalidAttachmentNotFound.setText("InvalidAttachment.NotFound");
        serviceErrors.add(invalidAttachmentNotFound);
        final Error invalidAttachmentIDNotFound = new Error();
        invalidAttachmentIDNotFound.setName("InvalidAttachmentID.NotFound");
        invalidAttachmentIDNotFound.setText("InvalidAttachmentID.NotFound");
        serviceErrors.add(invalidAttachmentIDNotFound);
        final Error invalidBlockDeviceMapping = new Error();
        invalidBlockDeviceMapping.setName("InvalidBlockDeviceMapping");
        invalidBlockDeviceMapping.setText("InvalidBlockDeviceMapping");
        serviceErrors.add(invalidBlockDeviceMapping);
        final Error invalidBundleIDNotFound = new Error();
        invalidBundleIDNotFound.setName("InvalidBundleID.NotFound");
        invalidBundleIDNotFound.setText("InvalidBundleID.NotFound");
        serviceErrors.add(invalidBundleIDNotFound);
        final Error invalidConversionTaskId = new Error();
        invalidConversionTaskId.setName("InvalidConversionTaskId");
        invalidConversionTaskId.setText("InvalidConversionTaskId");
        serviceErrors.add(invalidConversionTaskId);
        final Error invalidCustomerGatewayDuplicateIpAddress = new Error();
        invalidCustomerGatewayDuplicateIpAddress.setName("InvalidCustomerGateway.DuplicateIpAddress");
        invalidCustomerGatewayDuplicateIpAddress.setText("InvalidCustomerGateway.DuplicateIpAddress");
        serviceErrors.add(invalidCustomerGatewayDuplicateIpAddress);
        final Error invalidCustomerGatewayIdMalformed = new Error();
        invalidCustomerGatewayIdMalformed.setName("InvalidCustomerGatewayId.Malformed");
        invalidCustomerGatewayIdMalformed.setText("InvalidCustomerGatewayId.Malformed");
        serviceErrors.add(invalidCustomerGatewayIdMalformed);
        final Error invalidCustomerGatewayIDNotFound = new Error();
        invalidCustomerGatewayIDNotFound.setName("InvalidCustomerGatewayID.NotFound");
        invalidCustomerGatewayIDNotFound.setText("InvalidCustomerGatewayID.NotFound");
        serviceErrors.add(invalidCustomerGatewayIDNotFound);
        final Error invalidDeviceInUse = new Error();
        invalidDeviceInUse.setName("InvalidDevice.InUse");
        invalidDeviceInUse.setText("InvalidDevice.InUse");
        serviceErrors.add(invalidDeviceInUse);
        final Error invalidDhcpOptionIDNotFound = new Error();
        invalidDhcpOptionIDNotFound.setName("InvalidDhcpOptionID.NotFound");
        invalidDhcpOptionIDNotFound.setText("InvalidDhcpOptionID.NotFound");
        serviceErrors.add(invalidDhcpOptionIDNotFound);
        final Error invalidDhcpOptionsIDNotFound = new Error();
        invalidDhcpOptionsIDNotFound.setName("InvalidDhcpOptionsID.NotFound");
        invalidDhcpOptionsIDNotFound.setText("InvalidDhcpOptionsID.NotFound");
        serviceErrors.add(invalidDhcpOptionsIDNotFound);
        final Error invalidDhcpOptionsIdMalformed = new Error();
        invalidDhcpOptionsIdMalformed.setName("InvalidDhcpOptionsId.Malformed");
        invalidDhcpOptionsIdMalformed.setText("InvalidDhcpOptionsId.Malformed");
        serviceErrors.add(invalidDhcpOptionsIdMalformed);
        final Error invalidExportTaskIDNotFound = new Error();
        invalidExportTaskIDNotFound.setName("InvalidExportTaskID.NotFound");
        invalidExportTaskIDNotFound.setText("InvalidExportTaskID.NotFound");
        serviceErrors.add(invalidExportTaskIDNotFound);
        final Error invalidFilter = new Error();
        invalidFilter.setName("InvalidFilter");
        invalidFilter.setText("InvalidFilter");
        serviceErrors.add(invalidFilter);
        final Error invalidFlowLogIdNotFound = new Error();
        invalidFlowLogIdNotFound.setName("InvalidFlowLogId.NotFound");
        invalidFlowLogIdNotFound.setText("InvalidFlowLogId.NotFound");
        serviceErrors.add(invalidFlowLogIdNotFound);
        final Error invalidFormat = new Error();
        invalidFormat.setName("InvalidFormat");
        invalidFormat.setText("InvalidFormat");
        serviceErrors.add(invalidFormat);
        final Error invalidGatewayIDNotFound = new Error();
        invalidGatewayIDNotFound.setName("InvalidGatewayID.NotFound");
        invalidGatewayIDNotFound.setText("InvalidGatewayID.NotFound");
        serviceErrors.add(invalidGatewayIDNotFound);
        final Error invalidGroupDuplicate = new Error();
        invalidGroupDuplicate.setName("InvalidGroup.Duplicate");
        invalidGroupDuplicate.setText("InvalidGroup.Duplicate");
        serviceErrors.add(invalidGroupDuplicate);
        final Error invalidGroupIdMalformed = new Error();
        invalidGroupIdMalformed.setName("InvalidGroupId.Malformed");
        invalidGroupIdMalformed.setText("InvalidGroupId.Malformed");
        serviceErrors.add(invalidGroupIdMalformed);
        final Error invalidGroupInUse = new Error();
        invalidGroupInUse.setName("InvalidGroup.InUse");
        invalidGroupInUse.setText("InvalidGroup.InUse");
        serviceErrors.add(invalidGroupInUse);
        final Error invalidGroupNotFound = new Error();
        invalidGroupNotFound.setName("InvalidGroup.NotFound");
        invalidGroupNotFound.setText("InvalidGroup.NotFound");
        serviceErrors.add(invalidGroupNotFound);
        final Error invalidGroupReserved = new Error();
        invalidGroupReserved.setName("InvalidGroup.Reserved");
        invalidGroupReserved.setText("InvalidGroup.Reserved");
        serviceErrors.add(invalidGroupReserved);
        final Error invalidID = new Error();
        invalidID.setName("InvalidID");
        invalidID.setText("InvalidID");
        serviceErrors.add(invalidID);
        final Error invalidInput = new Error();
        invalidInput.setName("InvalidInput");
        invalidInput.setText("InvalidInput");
        serviceErrors.add(invalidInput);
        final Error invalidInstanceAttributeValue = new Error();
        invalidInstanceAttributeValue.setName("InvalidInstanceAttributeValue");
        invalidInstanceAttributeValue.setText("InvalidInstanceAttributeValue");
        serviceErrors.add(invalidInstanceAttributeValue);
        final Error invalidInstanceID = new Error();
        invalidInstanceID.setName("InvalidInstanceID");
        invalidInstanceID.setText("InvalidInstanceID");
        serviceErrors.add(invalidInstanceID);
        final Error invalidInstanceIDMalformed = new Error();
        invalidInstanceIDMalformed.setName("InvalidInstanceID.Malformed");
        invalidInstanceIDMalformed.setText("InvalidInstanceID.Malformed");
        serviceErrors.add(invalidInstanceIDMalformed);
        final Error invalidInstanceIDNotFound = new Error();
        invalidInstanceIDNotFound.setName("InvalidInstanceID.NotFound");
        invalidInstanceIDNotFound.setText("InvalidInstanceID.NotFound");
        serviceErrors.add(invalidInstanceIDNotFound);
        final Error invalidInstanceIDNotLinkable = new Error();
        invalidInstanceIDNotLinkable.setName("InvalidInstanceID.NotLinkable");
        invalidInstanceIDNotLinkable.setText("InvalidInstanceID.NotLinkable");
        serviceErrors.add(invalidInstanceIDNotLinkable);
        final Error invalidInstanceType = new Error();
        invalidInstanceType.setName("InvalidInstanceType");
        invalidInstanceType.setText("InvalidInstanceType");
        serviceErrors.add(invalidInstanceType);
        final Error invalidInterfaceIpAddressLimitExceeded = new Error();
        invalidInterfaceIpAddressLimitExceeded.setName("InvalidInterface.IpAddressLimitExceeded");
        invalidInterfaceIpAddressLimitExceeded.setText("InvalidInterface.IpAddressLimitExceeded");
        serviceErrors.add(invalidInterfaceIpAddressLimitExceeded);
        final Error invalidInternetGatewayIDNotFound = new Error();
        invalidInternetGatewayIDNotFound.setName("InvalidInternetGatewayID.NotFound");
        invalidInternetGatewayIDNotFound.setText("InvalidInternetGatewayID.NotFound");
        serviceErrors.add(invalidInternetGatewayIDNotFound);
        final Error invalidIPAddressInUse = new Error();
        invalidIPAddressInUse.setName("InvalidIPAddress.InUse");
        invalidIPAddressInUse.setText("InvalidIPAddress.InUse");
        serviceErrors.add(invalidIPAddressInUse);
        final Error invalidKeyFormat = new Error();
        invalidKeyFormat.setName("InvalidKey.Format");
        invalidKeyFormat.setText("InvalidKey.Format");
        serviceErrors.add(invalidKeyFormat);
        final Error invalidKeyPairDuplicate = new Error();
        invalidKeyPairDuplicate.setName("InvalidKeyPair.Duplicate");
        invalidKeyPairDuplicate.setText("InvalidKeyPair.Duplicate");
        serviceErrors.add(invalidKeyPairDuplicate);
        final Error invalidKeyPairFormat = new Error();
        invalidKeyPairFormat.setName("InvalidKeyPair.Format");
        invalidKeyPairFormat.setText("InvalidKeyPair.Format");
        serviceErrors.add(invalidKeyPairFormat);
        final Error invalidKeyPairNotFound = new Error();
        invalidKeyPairNotFound.setName("InvalidKeyPair.NotFound");
        invalidKeyPairNotFound.setText("InvalidKeyPair.NotFound");
        serviceErrors.add(invalidKeyPairNotFound);
        final Error invalidManifest = new Error();
        invalidManifest.setName("InvalidManifest");
        invalidManifest.setText("InvalidManifest");
        serviceErrors.add(invalidManifest);
        final Error invalidNetworkAclEntryNotFound = new Error();
        invalidNetworkAclEntryNotFound.setName("InvalidNetworkAclEntry.NotFound");
        invalidNetworkAclEntryNotFound.setText("InvalidNetworkAclEntry.NotFound");
        serviceErrors.add(invalidNetworkAclEntryNotFound);
        final Error invalidNetworkAclIDNotFound = new Error();
        invalidNetworkAclIDNotFound.setName("InvalidNetworkAclID.NotFound");
        invalidNetworkAclIDNotFound.setText("InvalidNetworkAclID.NotFound");
        serviceErrors.add(invalidNetworkAclIDNotFound);
        final Error invalidNetworkInterfaceAttachmentIDMalformed = new Error();
        invalidNetworkInterfaceAttachmentIDMalformed.setName("InvalidNetworkInterfaceAttachmentID.Malformed");
        invalidNetworkInterfaceAttachmentIDMalformed.setText("InvalidNetworkInterfaceAttachmentID.Malformed");
        serviceErrors.add(invalidNetworkInterfaceAttachmentIDMalformed);
        final Error invalidNetworkInterfaceIdMalformed = new Error();
        invalidNetworkInterfaceIdMalformed.setName("InvalidNetworkInterfaceId.Malformed");
        invalidNetworkInterfaceIdMalformed.setText("InvalidNetworkInterfaceId.Malformed");
        serviceErrors.add(invalidNetworkInterfaceIdMalformed);
        final Error invalidNetworkInterfaceIDNotFound = new Error();
        invalidNetworkInterfaceIDNotFound.setName("InvalidNetworkInterfaceID.NotFound");
        invalidNetworkInterfaceIDNotFound.setText("InvalidNetworkInterfaceID.NotFound");
        serviceErrors.add(invalidNetworkInterfaceIDNotFound);
        final Error invalidOptionConflict = new Error();
        invalidOptionConflict.setName("InvalidOption.Conflict");
        invalidOptionConflict.setText("InvalidOption.Conflict");
        serviceErrors.add(invalidOptionConflict);
        final Error invalidPermissionDuplicate = new Error();
        invalidPermissionDuplicate.setName("InvalidPermission.Duplicate");
        invalidPermissionDuplicate.setText("InvalidPermission.Duplicate");
        serviceErrors.add(invalidPermissionDuplicate);
        final Error invalidPermissionMalformed = new Error();
        invalidPermissionMalformed.setName("InvalidPermission.Malformed");
        invalidPermissionMalformed.setText("InvalidPermission.Malformed");
        serviceErrors.add(invalidPermissionMalformed);
        final Error invalidPermissionNotFound = new Error();
        invalidPermissionNotFound.setName("InvalidPermission.NotFound");
        invalidPermissionNotFound.setText("InvalidPermission.NotFound");
        serviceErrors.add(invalidPermissionNotFound);
        final Error invalidPlacementGroupDuplicate = new Error();
        invalidPlacementGroupDuplicate.setName("InvalidPlacementGroup.Duplicate");
        invalidPlacementGroupDuplicate.setText("InvalidPlacementGroup.Duplicate");
        serviceErrors.add(invalidPlacementGroupDuplicate);
        final Error invalidPlacementGroupInUse = new Error();
        invalidPlacementGroupInUse.setName("InvalidPlacementGroup.InUse");
        invalidPlacementGroupInUse.setText("InvalidPlacementGroup.InUse");
        serviceErrors.add(invalidPlacementGroupInUse);
        final Error invalidPlacementGroupUnknown = new Error();
        invalidPlacementGroupUnknown.setName("InvalidPlacementGroup.Unknown");
        invalidPlacementGroupUnknown.setText("InvalidPlacementGroup.Unknown");
        serviceErrors.add(invalidPlacementGroupUnknown);
        final Error invalidPolicyDocument = new Error();
        invalidPolicyDocument.setName("InvalidPolicyDocument");
        invalidPolicyDocument.setText("InvalidPolicyDocument");
        serviceErrors.add(invalidPolicyDocument);
        final Error invalidPrefixListIdMalformed = new Error();
        invalidPrefixListIdMalformed.setName("InvalidPrefixListId.Malformed");
        invalidPrefixListIdMalformed.setText("InvalidPrefixListId.Malformed");
        serviceErrors.add(invalidPrefixListIdMalformed);
        final Error invalidPrefixListIdNotFound = new Error();
        invalidPrefixListIdNotFound.setName("InvalidPrefixListId.NotFound");
        invalidPrefixListIdNotFound.setText("InvalidPrefixListId.NotFound");
        serviceErrors.add(invalidPrefixListIdNotFound);
        final Error invalidRequest = new Error();
        invalidRequest.setName("InvalidRequest");
        invalidRequest.setText("InvalidRequest");
        serviceErrors.add(invalidRequest);
        final Error invalidReservationIDMalformed = new Error();
        invalidReservationIDMalformed.setName("InvalidReservationID.Malformed");
        invalidReservationIDMalformed.setText("InvalidReservationID.Malformed");
        serviceErrors.add(invalidReservationIDMalformed);
        final Error invalidReservationIDNotFound = new Error();
        invalidReservationIDNotFound.setName("InvalidReservationID.NotFound");
        invalidReservationIDNotFound.setText("InvalidReservationID.NotFound");
        serviceErrors.add(invalidReservationIDNotFound);
        final Error invalidReservedInstancesId = new Error();
        invalidReservedInstancesId.setName("InvalidReservedInstancesId");
        invalidReservedInstancesId.setText("InvalidReservedInstancesId");
        serviceErrors.add(invalidReservedInstancesId);
        final Error invalidReservedInstancesOfferingId = new Error();
        invalidReservedInstancesOfferingId.setName("InvalidReservedInstancesOfferingId");
        invalidReservedInstancesOfferingId.setText("InvalidReservedInstancesOfferingId");
        serviceErrors.add(invalidReservedInstancesOfferingId);
        final Error invalidRouteMalformed = new Error();
        invalidRouteMalformed.setName("InvalidRoute.Malformed");
        invalidRouteMalformed.setText("InvalidRoute.Malformed");
        serviceErrors.add(invalidRouteMalformed);
        final Error invalidRouteNotFound = new Error();
        invalidRouteNotFound.setName("InvalidRoute.NotFound");
        invalidRouteNotFound.setText("InvalidRoute.NotFound");
        serviceErrors.add(invalidRouteNotFound);
        final Error invalidRouteTableIdMalformed = new Error();
        invalidRouteTableIdMalformed.setName("InvalidRouteTableId.Malformed");
        invalidRouteTableIdMalformed.setText("InvalidRouteTableId.Malformed");
        serviceErrors.add(invalidRouteTableIdMalformed);
        final Error invalidRouteTableIDNotFound = new Error();
        invalidRouteTableIDNotFound.setName("InvalidRouteTableID.NotFound");
        invalidRouteTableIDNotFound.setText("InvalidRouteTableID.NotFound");
        serviceErrors.add(invalidRouteTableIDNotFound);
        final Error invalidSecurityGroupIDNotFound = new Error();
        invalidSecurityGroupIDNotFound.setName("InvalidSecurityGroupID.NotFound");
        invalidSecurityGroupIDNotFound.setText("InvalidSecurityGroupID.NotFound");
        serviceErrors.add(invalidSecurityGroupIDNotFound);
        final Error invalidSecurityRequestHasExpired = new Error();
        invalidSecurityRequestHasExpired.setName("InvalidSecurity.RequestHasExpired");
        invalidSecurityRequestHasExpired.setText("InvalidSecurity.RequestHasExpired");
        serviceErrors.add(invalidSecurityRequestHasExpired);
        final Error invalidServiceName = new Error();
        invalidServiceName.setName("InvalidServiceName");
        invalidServiceName.setText("InvalidServiceName");
        serviceErrors.add(invalidServiceName);
        final Error invalidSnapshotIDMalformed = new Error();
        invalidSnapshotIDMalformed.setName("InvalidSnapshotID.Malformed");
        invalidSnapshotIDMalformed.setText("InvalidSnapshotID.Malformed");
        serviceErrors.add(invalidSnapshotIDMalformed);
        final Error invalidSnapshotInUse = new Error();
        invalidSnapshotInUse.setName("InvalidSnapshot.InUse");
        invalidSnapshotInUse.setText("InvalidSnapshot.InUse");
        serviceErrors.add(invalidSnapshotInUse);
        final Error invalidSnapshotNotFound = new Error();
        invalidSnapshotNotFound.setName("InvalidSnapshot.NotFound");
        invalidSnapshotNotFound.setText("InvalidSnapshot.NotFound");
        serviceErrors.add(invalidSnapshotNotFound);
        final Error invalidSpotDatafeedNotFound = new Error();
        invalidSpotDatafeedNotFound.setName("InvalidSpotDatafeed.NotFound");
        invalidSpotDatafeedNotFound.setText("InvalidSpotDatafeed.NotFound");
        serviceErrors.add(invalidSpotDatafeedNotFound);
        final Error invalidSpotFleetRequestConfig = new Error();
        invalidSpotFleetRequestConfig.setName("InvalidSpotFleetRequestConfig");
        invalidSpotFleetRequestConfig.setText("InvalidSpotFleetRequestConfig");
        serviceErrors.add(invalidSpotFleetRequestConfig);
        final Error invalidSpotFleetRequestIdMalformed = new Error();
        invalidSpotFleetRequestIdMalformed.setName("InvalidSpotFleetRequestId.Malformed");
        invalidSpotFleetRequestIdMalformed.setText("InvalidSpotFleetRequestId.Malformed");
        serviceErrors.add(invalidSpotFleetRequestIdMalformed);
        final Error invalidSpotFleetRequestIdNotFound = new Error();
        invalidSpotFleetRequestIdNotFound.setName("InvalidSpotFleetRequestId.NotFound");
        invalidSpotFleetRequestIdNotFound.setText("InvalidSpotFleetRequestId.NotFound");
        serviceErrors.add(invalidSpotFleetRequestIdNotFound);
        final Error invalidSpotInstanceRequestIDMalformed = new Error();
        invalidSpotInstanceRequestIDMalformed.setName("InvalidSpotInstanceRequestID.Malformed");
        invalidSpotInstanceRequestIDMalformed.setText("InvalidSpotInstanceRequestID.Malformed");
        serviceErrors.add(invalidSpotInstanceRequestIDMalformed);
        final Error invalidSpotInstanceRequestIDNotFound = new Error();
        invalidSpotInstanceRequestIDNotFound.setName("InvalidSpotInstanceRequestID.NotFound");
        invalidSpotInstanceRequestIDNotFound.setText("InvalidSpotInstanceRequestID.NotFound");
        serviceErrors.add(invalidSpotInstanceRequestIDNotFound);
        final Error invalidState = new Error();
        invalidState.setName("InvalidState");
        invalidState.setText("InvalidState");
        serviceErrors.add(invalidState);
        final Error invalidStateTransition = new Error();
        invalidStateTransition.setName("InvalidStateTransition");
        invalidStateTransition.setText("InvalidStateTransition");
        serviceErrors.add(invalidStateTransition);
        final Error invalidSubnetConflict = new Error();
        invalidSubnetConflict.setName("InvalidSubnet.Conflict");
        invalidSubnetConflict.setText("InvalidSubnet.Conflict");
        serviceErrors.add(invalidSubnetConflict);
        final Error invalidSubnetIDNotFound = new Error();
        invalidSubnetIDNotFound.setName("InvalidSubnetID.NotFound");
        invalidSubnetIDNotFound.setText("InvalidSubnetID.NotFound");
        serviceErrors.add(invalidSubnetIDNotFound);
        final Error invalidUserIDMalformed = new Error();
        invalidUserIDMalformed.setName("InvalidUserID.Malformed");
        invalidUserIDMalformed.setText("InvalidUserID.Malformed");
        serviceErrors.add(invalidUserIDMalformed);
        final Error invalidVolumeIDDuplicate = new Error();
        invalidVolumeIDDuplicate.setName("InvalidVolumeID.Duplicate");
        invalidVolumeIDDuplicate.setText("InvalidVolumeID.Duplicate");
        serviceErrors.add(invalidVolumeIDDuplicate);
        final Error invalidVolumeIDMalformed = new Error();
        invalidVolumeIDMalformed.setName("InvalidVolumeID.Malformed");
        invalidVolumeIDMalformed.setText("InvalidVolumeID.Malformed");
        serviceErrors.add(invalidVolumeIDMalformed);
        final Error invalidVolumeIDZoneMismatch = new Error();
        invalidVolumeIDZoneMismatch.setName("InvalidVolumeID.ZoneMismatch");
        invalidVolumeIDZoneMismatch.setText("InvalidVolumeID.ZoneMismatch");
        serviceErrors.add(invalidVolumeIDZoneMismatch);
        final Error invalidVolumeNotFound = new Error();
        invalidVolumeNotFound.setName("InvalidVolume.NotFound");
        invalidVolumeNotFound.setText("InvalidVolume.NotFound");
        serviceErrors.add(invalidVolumeNotFound);
        final Error invalidVolumeZoneMismatch = new Error();
        invalidVolumeZoneMismatch.setName("InvalidVolume.ZoneMismatch");
        invalidVolumeZoneMismatch.setText("InvalidVolume.ZoneMismatch");
        serviceErrors.add(invalidVolumeZoneMismatch);
        final Error invalidVpcEndpointIdMalformed = new Error();
        invalidVpcEndpointIdMalformed.setName("InvalidVpcEndpointId.Malformed");
        invalidVpcEndpointIdMalformed.setText("InvalidVpcEndpointId.Malformed");
        serviceErrors.add(invalidVpcEndpointIdMalformed);
        final Error invalidVpcEndpointIdNotFound = new Error();
        invalidVpcEndpointIdNotFound.setName("InvalidVpcEndpointId.NotFound");
        invalidVpcEndpointIdNotFound.setText("InvalidVpcEndpointId.NotFound");
        serviceErrors.add(invalidVpcEndpointIdNotFound);
        final Error invalidVpcIDNotFound = new Error();
        invalidVpcIDNotFound.setName("InvalidVpcID.NotFound");
        invalidVpcIDNotFound.setText("InvalidVpcID.NotFound");
        serviceErrors.add(invalidVpcIDNotFound);
        final Error invalidVpcPeeringConnectionIdMalformed = new Error();
        invalidVpcPeeringConnectionIdMalformed.setName("InvalidVpcPeeringConnectionId.Malformed");
        invalidVpcPeeringConnectionIdMalformed.setText("InvalidVpcPeeringConnectionId.Malformed");
        serviceErrors.add(invalidVpcPeeringConnectionIdMalformed);
        final Error invalidVpcPeeringConnectionIDNotFound = new Error();
        invalidVpcPeeringConnectionIDNotFound.setName("InvalidVpcPeeringConnectionID.NotFound");
        invalidVpcPeeringConnectionIDNotFound.setText("InvalidVpcPeeringConnectionID.NotFound");
        serviceErrors.add(invalidVpcPeeringConnectionIDNotFound);
        final Error invalidVpcRange = new Error();
        invalidVpcRange.setName("InvalidVpc.Range");
        invalidVpcRange.setText("InvalidVpc.Range");
        serviceErrors.add(invalidVpcRange);
        final Error invalidVpcState = new Error();
        invalidVpcState.setName("InvalidVpcState");
        invalidVpcState.setText("InvalidVpcState");
        serviceErrors.add(invalidVpcState);
        final Error invalidVpnConnectionID = new Error();
        invalidVpnConnectionID.setName("InvalidVpnConnectionID");
        invalidVpnConnectionID.setText("InvalidVpnConnectionID");
        serviceErrors.add(invalidVpnConnectionID);
        final Error invalidVpnConnectionIDNotFound = new Error();
        invalidVpnConnectionIDNotFound.setName("InvalidVpnConnectionID.NotFound");
        invalidVpnConnectionIDNotFound.setText("InvalidVpnConnectionID.NotFound");
        serviceErrors.add(invalidVpnConnectionIDNotFound);
        final Error invalidVpnGatewayAttachmentNotFound = new Error();
        invalidVpnGatewayAttachmentNotFound.setName("InvalidVpnGatewayAttachment.NotFound");
        invalidVpnGatewayAttachmentNotFound.setText("InvalidVpnGatewayAttachment.NotFound");
        serviceErrors.add(invalidVpnGatewayAttachmentNotFound);
        final Error invalidVpnGatewayIDNotFound = new Error();
        invalidVpnGatewayIDNotFound.setName("InvalidVpnGatewayID.NotFound");
        invalidVpnGatewayIDNotFound.setText("InvalidVpnGatewayID.NotFound");
        serviceErrors.add(invalidVpnGatewayIDNotFound);
        final Error invalidZoneNotFound = new Error();
        invalidZoneNotFound.setName("InvalidZone.NotFound");
        invalidZoneNotFound.setText("InvalidZone.NotFound");
        serviceErrors.add(invalidZoneNotFound);
        final Error legacySecurityGroup = new Error();
        legacySecurityGroup.setName("LegacySecurityGroup");
        legacySecurityGroup.setText("LegacySecurityGroup");
        serviceErrors.add(legacySecurityGroup);
        final Error maxIOPSLimitExceeded = new Error();
        maxIOPSLimitExceeded.setName("MaxIOPSLimitExceeded");
        maxIOPSLimitExceeded.setText("MaxIOPSLimitExceeded");
        serviceErrors.add(maxIOPSLimitExceeded);
        final Error maxSpotFleetRequestCountExceeded = new Error();
        maxSpotFleetRequestCountExceeded.setName("MaxSpotFleetRequestCountExceeded");
        maxSpotFleetRequestCountExceeded.setText("MaxSpotFleetRequestCountExceeded");
        serviceErrors.add(maxSpotFleetRequestCountExceeded);
        final Error maxSpotInstanceCountExceeded = new Error();
        maxSpotInstanceCountExceeded.setName("MaxSpotInstanceCountExceeded");
        maxSpotInstanceCountExceeded.setText("MaxSpotInstanceCountExceeded");
        serviceErrors.add(maxSpotInstanceCountExceeded);
        final Error networkAclEntryAlreadyExists = new Error();
        networkAclEntryAlreadyExists.setName("NetworkAclEntryAlreadyExists");
        networkAclEntryAlreadyExists.setText("NetworkAclEntryAlreadyExists");
        serviceErrors.add(networkAclEntryAlreadyExists);
        final Error networkAclEntryLimitExceeded = new Error();
        networkAclEntryLimitExceeded.setName("NetworkAclEntryLimitExceeded");
        networkAclEntryLimitExceeded.setText("NetworkAclEntryLimitExceeded");
        serviceErrors.add(networkAclEntryLimitExceeded);
        final Error networkAclLimitExceeded = new Error();
        networkAclLimitExceeded.setName("NetworkAclLimitExceeded");
        networkAclLimitExceeded.setText("NetworkAclLimitExceeded");
        serviceErrors.add(networkAclLimitExceeded);
        final Error nonEBSInstance = new Error();
        nonEBSInstance.setName("NonEBSInstance");
        nonEBSInstance.setText("NonEBSInstance");
        serviceErrors.add(nonEBSInstance);
        final Error notExportable = new Error();
        notExportable.setName("NotExportable");
        notExportable.setText("NotExportable");
        serviceErrors.add(notExportable);
        final Error operationNotPermitted = new Error();
        operationNotPermitted.setName("OperationNotPermitted");
        operationNotPermitted.setText("OperationNotPermitted");
        serviceErrors.add(operationNotPermitted);
        final Error outstandingVpcPeeringConnectionLimitExceeded = new Error();
        outstandingVpcPeeringConnectionLimitExceeded.setName("OutstandingVpcPeeringConnectionLimitExceeded");
        outstandingVpcPeeringConnectionLimitExceeded.setText("OutstandingVpcPeeringConnectionLimitExceeded");
        serviceErrors.add(outstandingVpcPeeringConnectionLimitExceeded);
        final Error pendingSnapshotLimitExceeded = new Error();
        pendingSnapshotLimitExceeded.setName("PendingSnapshotLimitExceeded");
        pendingSnapshotLimitExceeded.setText("PendingSnapshotLimitExceeded");
        serviceErrors.add(pendingSnapshotLimitExceeded);
        final Error privateIpAddressLimitExceeded = new Error();
        privateIpAddressLimitExceeded.setName("PrivateIpAddressLimitExceeded");
        privateIpAddressLimitExceeded.setText("PrivateIpAddressLimitExceeded");
        serviceErrors.add(privateIpAddressLimitExceeded);
        final Error requestResourceCountExceeded = new Error();
        requestResourceCountExceeded.setName("RequestResourceCountExceeded");
        requestResourceCountExceeded.setText("RequestResourceCountExceeded");
        serviceErrors.add(requestResourceCountExceeded);
        final Error reservedInstancesLimitExceeded = new Error();
        reservedInstancesLimitExceeded.setName("ReservedInstancesLimitExceeded");
        reservedInstancesLimitExceeded.setText("ReservedInstancesLimitExceeded");
        serviceErrors.add(reservedInstancesLimitExceeded);
        final Error resourceAlreadyAssociated = new Error();
        resourceAlreadyAssociated.setName("Resource.AlreadyAssociated");
        resourceAlreadyAssociated.setText("Resource.AlreadyAssociated");
        serviceErrors.add(resourceAlreadyAssociated);
        final Error resourceCountExceeded = new Error();
        resourceCountExceeded.setName("ResourceCountExceeded");
        resourceCountExceeded.setText("ResourceCountExceeded");
        serviceErrors.add(resourceCountExceeded);
        final Error resourceLimitExceeded = new Error();
        resourceLimitExceeded.setName("ResourceLimitExceeded");
        resourceLimitExceeded.setText("ResourceLimitExceeded");
        serviceErrors.add(resourceLimitExceeded);
        final Error routeAlreadyExists = new Error();
        routeAlreadyExists.setName("RouteAlreadyExists");
        routeAlreadyExists.setText("RouteAlreadyExists");
        serviceErrors.add(routeAlreadyExists);
        final Error routeLimitExceeded = new Error();
        routeLimitExceeded.setName("RouteLimitExceeded");
        routeLimitExceeded.setText("RouteLimitExceeded");
        serviceErrors.add(routeLimitExceeded);
        final Error routeTableLimitExceeded = new Error();
        routeTableLimitExceeded.setName("RouteTableLimitExceeded");
        routeTableLimitExceeded.setText("RouteTableLimitExceeded");
        serviceErrors.add(routeTableLimitExceeded);
        final Error rulesPerSecurityGroupLimitExceeded = new Error();
        rulesPerSecurityGroupLimitExceeded.setName("RulesPerSecurityGroupLimitExceeded");
        rulesPerSecurityGroupLimitExceeded.setText("RulesPerSecurityGroupLimitExceeded");
        serviceErrors.add(rulesPerSecurityGroupLimitExceeded);
        final Error securityGroupLimitExceeded = new Error();
        securityGroupLimitExceeded.setName("SecurityGroupLimitExceeded");
        securityGroupLimitExceeded.setText("SecurityGroupLimitExceeded");
        serviceErrors.add(securityGroupLimitExceeded);
        final Error securityGroupsPerInstanceLimitExceeded = new Error();
        securityGroupsPerInstanceLimitExceeded.setName("SecurityGroupsPerInstanceLimitExceeded");
        securityGroupsPerInstanceLimitExceeded.setText("SecurityGroupsPerInstanceLimitExceeded");
        serviceErrors.add(securityGroupsPerInstanceLimitExceeded);
        final Error securityGroupsPerInterfaceLimitExceeded = new Error();
        securityGroupsPerInterfaceLimitExceeded.setName("SecurityGroupsPerInterfaceLimitExceeded");
        securityGroupsPerInterfaceLimitExceeded.setText("SecurityGroupsPerInterfaceLimitExceeded");
        serviceErrors.add(securityGroupsPerInterfaceLimitExceeded);        
        final Error snapshotLimitExceeded = new Error();
        snapshotLimitExceeded.setName("SnapshotLimitExceeded");
        snapshotLimitExceeded.setText("SnapshotLimitExceeded");
        serviceErrors.add(snapshotLimitExceeded);
        final Error subnetLimitExceeded = new Error();
        subnetLimitExceeded.setName("SubnetLimitExceeded");
        subnetLimitExceeded.setText("SubnetLimitExceeded");
        serviceErrors.add(subnetLimitExceeded);
        final Error tagLimitExceeded = new Error();
        tagLimitExceeded.setName("TagLimitExceeded");
        tagLimitExceeded.setText("TagLimitExceeded");
        serviceErrors.add(tagLimitExceeded);
        final Error unknownVolumeType = new Error();
        unknownVolumeType.setName("UnknownVolumeType");
        unknownVolumeType.setText("UnknownVolumeType");
        serviceErrors.add(unknownVolumeType);
        final Error unsupported = new Error();
        unsupported.setName("Unsupported");
        unsupported.setText("Unsupported");
        serviceErrors.add(unsupported);
        final Error unsupportedOperation = new Error();
        unsupportedOperation.setName("UnsupportedOperation");
        unsupportedOperation.setText("UnsupportedOperation");
        serviceErrors.add(unsupportedOperation);
        final Error volumeInUse = new Error();
        volumeInUse.setName("VolumeInUse");
        volumeInUse.setText("VolumeInUse");
        serviceErrors.add(volumeInUse);
        final Error volumeLimitExceeded = new Error();
        volumeLimitExceeded.setName("VolumeLimitExceeded");
        volumeLimitExceeded.setText("VolumeLimitExceeded");
        serviceErrors.add(volumeLimitExceeded);
        final Error volumeTypeNotAvailableInZone = new Error();
        volumeTypeNotAvailableInZone.setName("VolumeTypeNotAvailableInZone");
        volumeTypeNotAvailableInZone.setText("VolumeTypeNotAvailableInZone");
        serviceErrors.add(volumeTypeNotAvailableInZone);
        final Error vpcCidrConflict = new Error();
        vpcCidrConflict.setName("VpcCidrConflict");
        vpcCidrConflict.setText("VpcCidrConflict");
        serviceErrors.add(vpcCidrConflict);
        final Error vPCIdNotSpecified = new Error();
        vPCIdNotSpecified.setName("VPCIdNotSpecified");
        vPCIdNotSpecified.setText("VPCIdNotSpecified");
        serviceErrors.add(vPCIdNotSpecified);
        final Error vpcEndpointLimitExceeded = new Error();
        vpcEndpointLimitExceeded.setName("VpcEndpointLimitExceeded");
        vpcEndpointLimitExceeded.setText("VpcEndpointLimitExceeded");
        serviceErrors.add(vpcEndpointLimitExceeded);
        final Error vpcLimitExceeded = new Error();
        vpcLimitExceeded.setName("VpcLimitExceeded");
        vpcLimitExceeded.setText("VpcLimitExceeded");
        serviceErrors.add(vpcLimitExceeded);
        final Error vpcPeeringConnectionAlreadyExists = new Error();
        vpcPeeringConnectionAlreadyExists.setName("VpcPeeringConnectionAlreadyExists");
        vpcPeeringConnectionAlreadyExists.setText("VpcPeeringConnectionAlreadyExists");
        serviceErrors.add(vpcPeeringConnectionAlreadyExists);
        final Error vPCResourceNotSpecified = new Error();
        vPCResourceNotSpecified.setName("VPCResourceNotSpecified");
        vPCResourceNotSpecified.setText("VPCResourceNotSpecified");
        serviceErrors.add(vPCResourceNotSpecified);
        final Error vpnConnectionLimitExceeded = new Error();
        vpnConnectionLimitExceeded.setName("VpnConnectionLimitExceeded");
        vpnConnectionLimitExceeded.setText("VpnConnectionLimitExceeded");
        serviceErrors.add(vpnConnectionLimitExceeded);
        final Error vpnGatewayAttachmentLimitExceeded = new Error();
        vpnGatewayAttachmentLimitExceeded.setName("VpnGatewayAttachmentLimitExceeded");
        vpnGatewayAttachmentLimitExceeded.setText("VpnGatewayAttachmentLimitExceeded");
        serviceErrors.add(vpnGatewayAttachmentLimitExceeded);
        final Error vpnGatewayLimitExceeded = new Error();
        vpnGatewayLimitExceeded.setName("VpnGatewayLimitExceeded");
        vpnGatewayLimitExceeded.setText("VpnGatewayLimitExceeded");
        serviceErrors.add(vpnGatewayLimitExceeded);
        return super.generateSourceFiles(serviceModel);
    }

    @Override
    protected SdkFileEntry generateRegionSourceFile(ServiceModel serviceModel) throws Exception {

        // Customized template for EC2 endpoints
        // TODO: cleanup with a proper dualstack endpoints support
        Template template = velocityEngine.getTemplate(
                "/com/amazonaws/util/awsclientgenerator/velocity/cpp/ec2/EC2EndpointEnumSource.vm",
                StandardCharsets.UTF_8.name());

        VelocityContext context = createContext(serviceModel);
        context.put("endpointMapping", computeEndpointMappingForService(serviceModel));

        String fileName = String.format("source/%sEndpoint.cpp", serviceModel.getMetadata().getClassNamePrefix());
        return makeFile(template, context, fileName, true);
    }
}
